package com.kunyi.web.service.file.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson.JSONObject;
import com.kunyi.platform.tool.api.JsonResult;
import com.kunyi.platform.tool.util.KyAssertUtil;
import com.kunyi.web.service.file.core.enums.ExportRequestStatusEnum;
import com.kunyi.web.service.file.core.enums.ExportTemplateStatusEnum;
import com.kunyi.web.service.file.core.handel.KunyiFileHandelContxt;
import com.kunyi.web.service.file.core.handel.KunyiRepository;
import com.kunyi.web.service.file.core.transform.ExportRequestTransform;
import com.kunyi.web.service.file.entity.domain.ExportRequest;
import com.kunyi.web.service.file.entity.domain.ExportTemplate;
import com.kunyi.web.service.file.service.IExportRequestService;
import com.kunyi.web.service.file.service.IExportService;
import com.kunyi.web.service.file.service.IExportTemplateService;
import com.kunyi.web.serviceapi.file.entity.dto.DataExportDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * @ClassName ExportServiceImpl
 * @Description 导出
 * @Author pengjunjun
 * @Date 2024/03/04
 * @Version 1.0
 **/
@Slf4j
@Service
public class ExportServiceImpl implements IExportService {
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private IExportTemplateService exportTemplateService;
    @Autowired
    private IExportRequestService exportRequestService;
    @Autowired
    private KunyiFileHandelContxt kunyiFileHandelContxt;

    @Override
    public String export(DataExportDto dto) {
        // 获取导出模版
        ExportTemplate template = exportTemplateService.getByCode(dto.getCode());
        KyAssertUtil.notNull(template, "未找到模板{}，请先上传模板！", dto.getCode());
        KyAssertUtil.notEquals(template.getStatus(), ExportTemplateStatusEnum.USE, "模板{}状态异常，请检查模板状态是否为使用中！", dto.getCode());
        // 设置默认值
        dto.setDefaultDataUrl(template.getDataUrl()).setDefaultNotifyUrl(template.getNotifyUrl());
        KyAssertUtil.notBlank(dto.getDataUrl(), "请传入数据地址，或者在模版{}中填入默认数据地址！", dto.getCode());
        // 记录请求
        String code = IdUtil.fastSimpleUUID();
        ExportRequest exportRequest = ExportRequestTransform.exportDto2Request(dto).setCode(code).setTemplateId(template.getId()).setStatus(ExportRequestStatusEnum.INIT.getCode());
        boolean save = exportRequestService.save(exportRequest);
        KyAssertUtil.isTrue(save, "保存导出请求失败！");
        threadPoolTaskExecutor.execute(() -> {
            exportData(dto, template, exportRequest.getId());
        });
        return code;
    }

    private void exportData(DataExportDto dto, ExportTemplate template, Long requestId) {
        File file = new File("tmp" + System.currentTimeMillis() + ".xlsx");
        // 生成文件
        KunyiRepository handel = kunyiFileHandelContxt.handel();
        try (InputStream is = handel.readStream(template.getFilePath()); ExcelWriter excelWriter = EasyExcel.write(file).withTemplate(is).build()) {
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            // 获取数据
            Integer pageNumTotal = dto.getTotal() / dto.getPageSize();
            if (dto.getTotal() % dto.getPageSize() > 0) {
                pageNumTotal++;
            }
            exportRequestService.changeStatus(requestId, ExportRequestStatusEnum.PROCESS.getCode());
            for (int i = 0; i < pageNumTotal; i++) {
                final Integer pageNum = i + 1;
                JSONObject param = new JSONObject();
                if (StrUtil.isNotBlank(dto.getParam())) {
                    param = JSONObject.parseObject(dto.getParam());
                }
                param.put("pageNum", pageNum);
                param.put("pageSize", dto.getPageSize());
                HttpEntity<JSONObject> request = new HttpEntity<>(param);
                ResponseEntity<JsonResult> response = restTemplate.postForEntity(dto.getDataUrl(), request, JsonResult.class);
                log.info("resp:{}", response.getBody());
                List data = (List) response.getBody().getData();
                excelWriter.fill(data, writeSheet);
                // 更新条数
                exportRequestService.changeSuccessTotal(requestId, data.size());
            }
        } catch (IOException e) {
            exportRequestService.changeStatus(requestId, ExportRequestStatusEnum.FAIL.getCode());
        }
        // 将文件上传到服务器中
        KunyiRepository handels = kunyiFileHandelContxt.handel();
        String fileUrl = handels.upload(file);
        exportRequestService.success(requestId, fileUrl);
        boolean delete = file.delete();// 删除临时文件
        if (!delete) {
            log.error("删除临时文件{}失败", requestId);
        }
    }
}
